package raft

import (
	"reflect"
	"sync"
)

// eventDispatcher负责管理命名事件的侦听器
// 并向这些侦听器发送事件通知。
type eventDispatcher struct {
	sync.RWMutex
	source    interface{}
	listeners map[string]eventListeners
}

// EventListener是一个可以接收事件通知的函数。
type EventListener func(Event)

// EventListeners表示单个侦听器的集合。
type eventListeners []EventListener

// newEventDispatcher创建一个新的eventDispatcher实例。
func newEventDispatcher(source interface{}) *eventDispatcher {
	return &eventDispatcher{
		source:    source,
		listeners: make(map[string]eventListeners),
	}
}

// AddEventListener为给定事件类型添加侦听器函数。
func (d *eventDispatcher) AddEventListener(typ string, listener EventListener) {
	d.Lock()
	defer d.Unlock()
	d.listeners[typ] = append(d.listeners[typ], listener)
}

// RemoveEventListener删除给定事件类型的侦听器函数。
func (d *eventDispatcher) RemoveEventListener(typ string, listener EventListener) {
	d.Lock()
	defer d.Unlock()

	// 获取一次对函数指针的引用。
	ptr := reflect.ValueOf(listener).Pointer()

	// 按指针查找侦听器并将其删除。
	listeners := d.listeners[typ]
	for i, l := range listeners {
		if reflect.ValueOf(l).Pointer() == ptr {
			d.listeners[typ] = append(listeners[:i], listeners[i+1:]...)
		}
	}
}

// DispatchEvent调度一个事件。
func (d *eventDispatcher) DispatchEvent(e Event) {
	d.RLock()
	defer d.RUnlock()

	// 自动设置事件源。
	if e, ok := e.(*event); ok {
		e.source = d.source
	}

	// 将事件分派给所有侦听器。
	for _, l := range d.listeners[e.Type()] {
		l(e)
	}
}
